package com.gec.component;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

import com.gec.exception.ResNotFoundException;

/**
 * @Author Str
 * @Date 2021/10/18 14:19
 * @Description :web容器（构造器，相当于web.xml）
 */
public class WebContainer {
    //{1}本地资源路径（方便给外部层序访问）
    public static String basePath = "D:\\Projects\\web\\";
    //{2}映射配置配置清单 [充当配置文件]
    private Map<String,String> webXML = new HashMap();
    //{3}servlet Map 容器
    private Map<String,HttpServlet> servletMap = new HashMap();

    //{4}创建构造器
    public WebContainer(){
        //{1}做 Servlet 注册.[等 Servlet 存在时再用]
        webXML.put("/Login","com.gec.web.LoginServlet");
        //webXML.put("/Register","com.gec.web.RegisterServlet");

        //{2}直接创建 DefaultServlet 并存入 Map.
        HttpServlet defServlet = new DefaultServlet();
        servletMap.put("DefaultServlet", defServlet);
    }

    boolean isWork = true;
    public void startServer(int port)
            throws IOException {
        //{1}创建服务端套接字
        ServerSocket server = new ServerSocket( port );
        print("+----------------[SimpleHttpServer1.0]----------------------------+");
        print("port:"+ port);
        print("+-----------------------------------------------------------------+");
        while( isWork ){
            //{2}accept 获取客户端连接.
            Socket socket = server.accept();
            //{3}创建 RequestTask 任务
            //   将自己传进入(方便回调)
            RequestTask task = new RequestTask(
                    this, socket );
            //{4}创建 线程并执行任务。
            new Thread( task ).start();
        }
    }

    //{5}以下方法是从容器查找 Servlet
    public HttpServlet findServlet( String URI )
            throws ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        //{1}先从容器中获取 Servlet 出来(根据映射地址获取)
        HttpServlet servlet = servletMap.get( URI );
        //{2}不为 null 直接返回
        if( servlet!=null ){  //{ps}正常的..
            return servlet;
        }
        print("容器中不存在对应映射的 Servlet ["+ URI +"]");
        //{3}没有则从 Web.xml 中查找是否有注册。
        //clsPath: com.gec.LoginServlet [类地址]
        String clsPath = webXML.get( URI );
        if( clsPath==null ){
            print("容器中没有注册 URI = "+ URI );
            return null;
        }
        //{4}有注册, 获取类路径描述字节码对象。
        Class cls = Class.forName( clsPath );
        //{5}反射创建 Servlet 对象。
        servlet = (HttpServlet)cls.newInstance();
        //{6}将 Servlet 存入容器中。
        servletMap.put("/Login", servlet);
        //{7}返回 Servlet 对象。
        return servlet;
    }

    //{6}调用  servlet 的 doGet / doPost 方法
    public void callServlet(HttpServlet servlet,
                            HttpServletRequest req,
                            HttpServletResponse resp)
            throws IOException {
        //{1}获取 req 请求方式
        String method = req.getMethod();
        //{2}判断是 GET / POST 方式, 决定调用什么方法。
        if("GET".equals(method)){
            servlet.doGet(req, resp);
        }else if ("POST".equals(method)){
            servlet.doPost(req, resp);
        }
    }

    //{8}查找普通的资源: htm, css, jpg, js等文件
    public void callDefaultServlet(
            String resPath,
            HttpServletRequest req,
            HttpServletResponse resp )
            throws ResNotFoundException, IOException {
        //{ps} resPath = /login.htm
        //{1}去除第一个斜杠
        resPath = resPath.substring(1); //结束: login.htm
        resPath = resPath.replace("/", "\\");
        //{2}拼接地址: d:\apk\web2163\login.htm
        String path = basePath + resPath;
        File file = new File( path );
        if( !file.exists() ){
            throw new ResNotFoundException(
                    "资源找不到:"+ path);
        }
        //{2}找默认 Servlet 来处理静态资源
        HttpServlet servlet = servletMap.get("DefaultServlet");
        //{3}调用它的 doGet 方法处理。
        servlet.doGet(req, resp);
    }



    private void print(Object obj) {
        System.out.println("{WebContainer}"+ obj);
    }
}
